package com.magicalcoder.pigeon.client;

import com.magicalcoder.pigeon.common.dto.RmtAddress;
import com.magicalcoder.pigeon.common.message.PigeonRequest;
import com.magicalcoder.pigeon.common.message.PigeonResponse;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;

import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutionException;

/**
 * Created by hzhedongyu on 2017/5/27.
 * 这个实例从连接到释放 一直承担这所有客户端的通信服务 实例要复用 而不是仅仅用一次重新new 这个是关键
 */
public class NettyClientHandler extends SimpleChannelInboundHandler<PigeonResponse> {

    private RmtAddress rmtAddress;
    private String randomId;//随机

    public RmtAddress getRmtAddress() {
        return rmtAddress;
    }

    public String getRandomId() {
        return randomId;
    }

    public NettyClientHandler(String randomId, RmtAddress rmtAddress) {
        this.randomId = randomId;
        this.rmtAddress = rmtAddress;
    }

    private ConcurrentHashMap<String,ClientFuture> resultHoldMap = new ConcurrentHashMap<>();

    private ChannelHandlerContext ctx;

    @Override
    public void channelRegistered(ChannelHandlerContext ctx) throws Exception {
        super.channelRegistered(ctx);
        this.ctx = ctx;
    }

    @Override
    protected void channelRead0(ChannelHandlerContext channelHandlerContext, PigeonResponse guguResponse) throws Exception {
        parseResponse(guguResponse);
    }

    private void parseResponse(PigeonResponse response){
        ClientFuture future = resultHoldMap.get(response.getRequestId());
        if(future!=null){
            future.finish(response);
        }else {
            future.finish(null);
        }
        resultHoldMap.remove(response.getRequestId());
    }

    public void removeRequestFromHoldMap(String requestId){
        resultHoldMap.remove(requestId);
    }

    public ClientFuture requestServer(PigeonRequest request) throws ExecutionException, InterruptedException {
        ClientFuture future = new ClientFuture();
        resultHoldMap.put(request.getRequestId(),future);
        ctx.writeAndFlush(request);
        return future;
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        super.exceptionCaught(ctx, cause);
        cause.printStackTrace();
//        System.out.println("客户端异常"+randomId);
//        ClientHandlerManager.get().remove(randomId);//这里到底要不要清理呢 会不会网络异常呢 服务端好好的 TODO 3
//        ctx.close();

    }

    //释放客户端
    public void close() {
        ctx.writeAndFlush(Unpooled.EMPTY_BUFFER).addListener(ChannelFutureListener.CLOSE);
        resultHoldMap.clear();
    }

    //当持有连接为空时 说明handler当前空闲
    public boolean isWorking(){
        return !resultHoldMap.isEmpty();
    }
}
